import json
import os
import sys
import numpy
from numpy import zeros as np_zeros
from numpy import reshape as np_reshape

def DumpWt(a, wordLen, shfLeft, sublineLen = 5, isUnsigned = False, sublineSep = [' ', '\n\t'], isAlignTo4B = True):
    # a must have output channel as the last shape
    chnCnt = a.shape[0] ; oldShape = a.shape
    wtPerChn = a.size // chnCnt
    cnt = a.size
    sublinePerLine = len(sublineSep)
    nMax = (1 << wordLen) / 2 - 1
    if wordLen <= 8:
        sIntFmt = '0x%02x,'
    else:
        sIntFmt = '%d,'
    b = np_reshape(a, -1, 'C')
    bOut = np_zeros((cnt))
    sVal = '' ; lineNdx = 0 ; itemNdx = 0
    ndx = 0 ; chnNdx = 0 ; inChnOfs = 0 ; maxVal = 2 ** wordLen if isUnsigned is True else 2 ** (wordLen - 1)
    lstSVals = []
    while ndx < cnt:
        if wtPerChn > 1 and inChnOfs == 0:
            pass
            #sVal += '// Out channel %d\n\t' % chnNdx
        fVal = b[ndx]
        if (shfLeft >= 0):
            fVal *= 1 << shfLeft
        else:
            fVal /= 1 << -shfLeft
        nVal = int(fVal)
        if nVal >= maxVal:
            nVal = maxVal - 1
        elif nVal < -maxVal:
            nVal = -maxVal
        if nVal < 0:
            if wordLen <= 8:
                pass
                # nVal = 256 + nVal
            else:
                pass
                # nVal = 65536 + nVal
        bOut[ndx] = nVal
        ndx += 1
        sVal += sIntFmt % (nVal)
        itemNdx += 1
        if itemNdx == sublineLen:
            itemNdx = 0 ; lineSep = sublineSep[lineNdx % sublinePerLine]
            if '\n' in lineSep:
                sVal += ' // %d' % (ndx)
            sVal += lineSep
            lineNdx += 1
            if lineNdx % 200 == 0:
                lstSVals.append(sVal)
                sVal = ''
                print('\r%.1f%%' % (ndx * 100 / cnt ), end='')
        if wtPerChn > 1:
            inChnOfs += 1
            if inChnOfs == wtPerChn:
                if sVal[-2] != '\n':
                    sVal += '\n\t'
                inChnOfs = 0 ; chnNdx += 1
                itemNdx = 0 ; lineNdx = 0
    if len(sVal) > 0 and sVal[-1] == '\n':
        sVal = sVal[:-1]
    if isAlignTo4B is True and cnt % 4 != 0:
        for i in range(4 - cnt % 4):
            sVal += '0,'
    lstSVals.append(sVal)
    sVal = ''.join(lstSVals)
    print('.')
    return sVal


if __name__ == '__main__':

    if len(sys.argv) < 2:
        print('command: pyxxd_wav.py wavfile [.h file]. if \'.h file\' is ignored then .h is appended to input file as output')
        exit(0)
    else:

        if len(sys.argv) >= 3:
            headerFile = sys.argv[2]
            mainname = os.path.split(headerFile)[1]
        else:
            headerFile = sys.argv[1] + '.h'
        
        mainname = os.path.split(headerFile)[1]
        mainname = os.path.splitext(mainname)[0]
        mainname = mainname.replace('-', '_')
        mainname = os.path.splitext(mainname)[0]
    
    fd = open(sys.argv[1], 'rb')
    aryBin = numpy.fromfile(fd, dtype='int16')
    aryBin = aryBin[44//2:]
    # aryBin = numpy.asarray(aryBin, dtype="int16")
    print(len(aryBin))
    fd.close()
    print('writing to %s' % (headerFile))
    sVal = DumpWt(aryBin, 16, 0, 8, True) + '\n'
    sPrefix = 'static const int16_t %s[] __ALIGNED(16) = {\n    ' % (mainname)
    sPostFix = '};\nstatic const unsigned int %s_len = %d;\n' % (mainname, len(aryBin))
    with open(headerFile, 'w') as fd:
        fd.write(sPrefix + sVal + sPostFix)

    print('done')


